package com.wangsd.web.face.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangsd.common.utils.DateUtils;
import com.wangsd.common.utils.HttpClientUtils;
import com.wangsd.common.utils.SMSUtils;
import com.wangsd.web.common.entity.WxMessage;
import com.wangsd.web.face.entity.Member;
import com.wangsd.web.face.entity.MemberAccountDetail;
import com.wangsd.web.face.entity.Merchant;
import com.wangsd.web.face.entity.TOrder;
import com.wangsd.web.face.mapper.MemberMapper;
import com.wangsd.web.face.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator
 * @since 2019-10-23
 */
@Service
@Slf4j
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

    @Value("${service.authApiUrl}")
    private String wechatUrl;
    @Value("${service.url}")
    private String serviceUrl;
    @Resource
    MemberMapper memberMapper;
    @Autowired
    MerchantService merchantService;
    @Autowired
    ServiceBusinessService serviceBusinessService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    TOrderService orderService;
    @Autowired
    MemberAccountDetailService memberAccountDetailService;


    @Override
    public IPage<Member> selectList(Integer pageNum, Integer pageSize, Member params, String code) {
        Page<Member> page = new Page<>(pageNum, pageSize);
        IPage<Member> resultIPage = memberMapper.selectListXml(page, params, code);
        return resultIPage;
    }

    @Override
    public void addOrUpdate(Member params) {
        if (params.getId() != null) {
            memberMapper.updateById(params);
        } else {
            memberMapper.insert(params);

            //保留检索CODE
            Merchant merchant = merchantService.getById(params.getMerchantId());
            params.setCode(merchant.getCode());
            memberMapper.updateById(params);
        }
    }

    @Override
    public void checkIsToMember(Long merchantId, String openId, String subOpenId, String phone, Integer isSend, Long orderId, String payType) {

        //有会员电话
        if (StringUtils.isNotBlank(phone)) {
            //查询会员信息
            QueryWrapper queryPhone = new QueryWrapper();
            queryPhone.eq("merchant_id", merchantId);
            queryPhone.eq("mobile", phone);
            queryPhone.eq("deleted", 0);
            queryPhone.eq("status", 1);
            Member member = memberMapper.selectOne(queryPhone);
            if (member != null) {
                //微信支付
                if (payType.equals("WXPAY")) {
                    //第一次支付，保存服务商openId
                    if (StringUtils.isBlank(member.getOpenId())) {
                        if (member.getSubOpenId().equals(subOpenId)) {
                            Member upMembre = new Member();
                            upMembre.setId(member.getId());
                            upMembre.setOpenId(openId);
                            memberMapper.updateById(upMembre);
                        }
                    }
                }
                //操作会员变动
                this.doMemberAccountChange(merchantId, orderId, member, isSend);
            }
        } else { //没有会员电话（但不排除已经是会员没输入会员电话）
            //只处理微信的支付
            if (payType.equals("WXPAY")) {
                //商户信息
                Merchant merchant = merchantService.getById(merchantId);
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("merchant_id", merchantId);
                queryWrapper.eq("sub_open_id", subOpenId);
                queryWrapper.eq("deleted", 0);
                Member member = memberMapper.selectOne(queryWrapper);

                if (member != null && member.getStatus() == 1) { //没输入手机号码，是会员
                    this.doMemberAccountChange(merchantId, orderId, member, isSend);
                } else {
                    //发送会员邀请模板消息
                    if (merchant.getIsMember() == 1 && isSend == 2) {//开启会员通知，并且已经关注公众号
                        //sendWxTempLateRegist(merchant, subOpenId);
                    }
                }
            }
        }
    }

    /**
     * 处理会员积分变动，记录，消息推送
     *
     * @param merchantId 商户id
     * @param orderId    订单ID
     * @param member     会员
     * @param isSend     是否关注发送
     */
    public void doMemberAccountChange(Long merchantId, Long orderId, Member member, Integer isSend) {
        Merchant merchant = merchantService.getById(merchantId);
        TOrder order = orderService.getById(orderId);
        //不计算代金券的支付金额
        Long payTotal = (order.getMemberTotalFee() == null || order.getMemberTotalFee() == 0 ? order.getOrderTotalFee() : order.getMemberTotalFee());
        //计算获得的积分
        Long integral = (payTotal / merchant.getMonetary());

        //修改会员积分
        Member upMembre = new Member();
        upMembre.setId(member.getId());
        upMembre.setTotalIntegral(member.getTotalIntegral() + integral);
        memberMapper.updateById(upMembre);

        //添加会员积分变动记录
        MemberAccountDetail detail = new MemberAccountDetail();
        detail.setAmount(integral);
        detail.setMemberId(member.getId());
        BigDecimal bg = new BigDecimal(payTotal * 0.01);
        DecimalFormat df1 = new DecimalFormat("0.00");
        String str = df1.format(bg);
        detail.setRemark("消费" + str + "元");
        detail.setStatus(1);
        detail.setType(1);
        memberAccountDetailService.saveOrUpdate(detail);


        if (merchant.getIsMember() == 1 && isSend == 2 && StringUtils.isNotBlank(member.getSubOpenId())) {//关注了商户公众号
            //发送积分变动通知
            this.sendWxTempLateIntegral(merchant, order, member, integral, 1);
        }

    }

    /**
     * 积分变动通知
     *
     * @param merchant
     * @param order
     * @param member
     * @param integral
     * @param status
     */
    private void sendWxTempLateIntegral(Merchant merchant, TOrder order, Member member, Long integral, Integer status) {
        //单人发送模板消息请求地址
        String tempLateUrl = wechatUrl + "/api/wxTemplate/sendTemplate";
        //消息内容
        WxMessage wxMessage = new WxMessage();
        wxMessage.setFirst("您在" + order.getStoreName() + "的积分发生了变动");
        wxMessage.setKeyword1(order.getStoreName());
        //处理实际支付金额
        Long payTotal = order.getRealPayFee() != null && order.getRealPayFee() > 0 ? order.getRealPayFee()//实际支付金额
                : (order.getMemberTotalFee() != null && order.getMemberTotalFee() > 0 ? order.getMemberTotalFee()//会员价
                : order.getOrderTotalFee());//原价
        BigDecimal bg = new BigDecimal(payTotal * 0.01);
        DecimalFormat df1 = new DecimalFormat("0.00");
        String str = df1.format(bg);
        wxMessage.setKeyword2(str);

        wxMessage.setKeyword3(DateUtils.formatDate(order.getCreatedTime(), "yyyy-MM-dd HH:mm"));
        wxMessage.setKeyword4((status == 1 ? "+" : "-") + integral);
        wxMessage.setKeyword5(member.getTotalIntegral() + "");
        wxMessage.setRemark("点击查看更多详情");
        //跳转小程序设置
        if (StringUtils.isNotBlank(merchant.getMiniAppid())) {
            wxMessage.setMiniAppid(merchant.getMiniAppid());
            wxMessage.setPagePath("pages/user/index");
        }

        //发送设置
        Map params = new HashMap();
        params.put("wxMessage", JSON.toJSONString(wxMessage));//消息内容体String
        params.put("templateId", "OPENTM417733533");//模板消息ID
        params.put("openId", member.getSubOpenId());
        params.put("appId", merchant.getSubAppId());
        String result = HttpClientUtils.post(tempLateUrl, params, "UTF-8");
        System.out.println(result);
    }

    /**
     * 会员注册邀请
     *
     * @param merchant
     * @param subOpenId
     */
    private void sendWxTempLateRegist(Merchant merchant, String subOpenId) {
        //单人发送模板消息请求地址
        String tempLateUrl = wechatUrl + "/api/wxTemplate/sendTemplate";
        //消息内容
        WxMessage wxMessage = new WxMessage();
        wxMessage.setFirst("会员卡免费办理中");
        wxMessage.setKeyword1(merchant.getName() + "邀请您办理一张会员卡，以后可以享受优惠，还可以用积分兑换礼品哦~");
        wxMessage.setKeyword2(DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm"));
        wxMessage.setRemark("了解更多详情信息，请点击查看！");
        //跳转小程序设置
        if (StringUtils.isNotBlank(merchant.getMiniAppid())) {
            wxMessage.setMiniAppid(merchant.getMiniAppid());
            wxMessage.setPagePath("pages/user/index");
        }
        //发送设置
        Map params = new HashMap();
        params.put("wxMessage", JSON.toJSONString(wxMessage));//消息内容体String
        params.put("templateId", "OPENTM411244264");//模板消息ID
        params.put("openId", subOpenId);
        params.put("appId", merchant.getSubAppId());
        String result = HttpClientUtils.post(tempLateUrl, params, "UTF-8");
        System.out.println(result);
    }

    @Override
    public Member selectByMerchantIdAndOpenId(Long merchantId, String openId, String subOpenId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("merchant_id", merchantId);
        if (StringUtils.isNotBlank(openId))
            queryWrapper.eq("open_id", openId);
        if (StringUtils.isNotBlank(subOpenId))
            queryWrapper.eq("sub_open_id", subOpenId);
        queryWrapper.eq("deleted", 0);
        Member member = memberMapper.selectOne(queryWrapper);
        return member;
    }

    @Override
    public Member selectByMerchantIdAndMobileAndStatus(Long merchantId, String mobile, Integer status) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("merchant_id", merchantId);
        if (StringUtils.isNotBlank(mobile))
            queryWrapper.eq("mobile", mobile);
        if (status != null)
            queryWrapper.eq("status", status);
        queryWrapper.eq("deleted", 0);
        Member member = memberMapper.selectOne(queryWrapper);
        return member;
    }


    @Override
    public String getValidateCode(String phone) {
        String validateCode;
        /*如果redis里面有验证码直接从redis中获取，最后通过短信方式发送*/
        String code = (String) redisTemplate.opsForValue().get(phone);
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(code)) {
            validateCode = code;
            redisTemplate.opsForValue().set(phone, code, 30, TimeUnit.MINUTES);
        } else {
            validateCode = String.valueOf(new Random().nextInt(899999) + 100000);
            /*将获取到的验证码存到redis里面*/
            redisTemplate.opsForValue().set(phone, validateCode, 30, TimeUnit.MINUTES);
        }
        /*根据电话号码获取手机验证码,调用短信验证api*/
        JSONObject jsonObject = SMSUtils.sendXSXXsms(phone, validateCode);
        if ("0".equals(jsonObject.get("status") + "")) {
            return validateCode;
        } else {
            return null;
        }

    }

    @Override
    public Member selectByMiniOpenId(String miniOpenId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("mini_open_id", miniOpenId);
        Member member = memberMapper.selectOne(queryWrapper);
        return member;
    }

    @Override
    @Transactional
    public void register(Member member) {
        Member old = selectByMiniOpenId(member.getMiniOpenId());
        if (old != null) {
            /*当会员中保存头像或者手机号是，授权成认证会员*/
            if (old.getAvatarUrl() != null && member.getMobile() != null) {
                member.setStatus(1);
            }

            member.setId(old.getId());
            memberMapper.updateById(member);
        } else {
            memberMapper.insert(member);
        }
    }

    @Override
    public void sendTemplateMsg(String openid, String cardNo, String unionId, Merchant merchant) {
        if (StringUtils.isBlank(unionId)) {
            log.info("unionId为空，不执行后续查询openId！");
            return;
        }


        //单人发送模板消息请求地址
        String tempUrl = wechatUrl + "/api/wxTemplate/sendTemplate";
        //消息内容
        WxMessage wxMessage = new WxMessage();
        wxMessage.setFirst("会员注册成功");
        wxMessage.setKeyword1("会员卡号:" + cardNo);
        wxMessage.setKeyword2(DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
        wxMessage.setRemark("了解更多详情信息，请点击查看！");
        //跳转用户会员中心
        //跳转小程序设置
        if (StringUtils.isNotBlank(merchant.getMiniAppid())) {
            wxMessage.setMiniAppid(merchant.getMiniAppid());
            wxMessage.setPagePath("pages/user/index");
        }
        //发送设置
        Map params = new HashMap();
        params.put("templateId", "OPENTM411984350");//模板消息ID
        params.put("wxMessage", JSON.toJSONString(wxMessage));//消息内容体String
        params.put("openId", openid);
        params.put("appId", merchant.getSubAppId());
        try {
            String sendResult = HttpClientUtils.post(tempUrl, params, "UTF-8");
            log.info("发送模板消息通知结果：" + sendResult);
        } catch (Exception e) {
            log.error("会员注册发送模板消息失败！", e);
        }
    }

    @Override
    public Member selectByMerchantIdAndSubOpenIdAndStatus(Long merchantId, String subOpenId, Integer status) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("merchant_id", merchantId);
        if (StringUtils.isNotBlank(subOpenId))
            queryWrapper.eq("sub_open_id", subOpenId);
        if (status != null)
            queryWrapper.eq("status", status);
        queryWrapper.eq("deleted", 0);
        Member member = memberMapper.selectOne(queryWrapper);
        return member;
    }
}
